/**
 * WebRTC 测试客户端
 * 包含详细的日志记录和错误诊断功能
 */

class WebRTCTestClient {
    constructor() {
        this.ws = null;
        this.pc = null;
        this.localStream = null;
        this.remoteStream = null;
        this.connectionState = 'disconnected';
        this.testStartTime = null;
        this.statsInterval = null;
        
        // DOM元素
        this.elements = {
            serverUrl: document.getElementById('serverUrl'),
            enableStun: document.getElementById('enableStun'),
            stunServer: document.getElementById('stunServer'),
            stunServerGroup: document.getElementById('stunServerGroup'),
            stunPreset: document.getElementById('stunPreset'),
            connectBtn: document.getElementById('connectBtn'),
            disconnectBtn: document.getElementById('disconnectBtn'),
            startTestBtn: document.getElementById('startTestBtn'),
            stopTestBtn: document.getElementById('stopTestBtn'),
            clearLogBtn: document.getElementById('clearLogBtn'),
            connectionStatus: document.getElementById('connectionStatus'),
            progressFill: document.getElementById('progressFill'),
            wsStatus: document.getElementById('wsStatus'),
            pcStatus: document.getElementById('pcStatus'),
            iceStatus: document.getElementById('iceStatus'),
            mediaStatus: document.getElementById('mediaStatus'),
            localVideo: document.getElementById('localVideo'),
            remoteVideo: document.getElementById('remoteVideo'),
            logContainer: document.getElementById('logContainer')
        };
        
        // STUN预设配置
        this.stunPresets = {
            google: 'stun:stun.l.google.com:19302,stun:stun1.l.google.com:19302',
            cloudflare: 'stun:stun.cloudflare.com:3478',
            custom: ''
        };
        
        this.initializeEventListeners();
        this.log('系统', 'WebRTC测试客户端初始化完成', 'info');
        this.checkBrowserSupport();
    }
    
    initializeEventListeners() {
        this.elements.connectBtn.addEventListener('click', () => this.connect());
        this.elements.disconnectBtn.addEventListener('click', () => this.disconnect());
        this.elements.startTestBtn.addEventListener('click', () => this.startWebRTCTest());
        this.elements.stopTestBtn.addEventListener('click', () => this.stopWebRTCTest());
        this.elements.clearLogBtn.addEventListener('click', () => this.clearLog());
        
        // STUN配置相关事件
        this.elements.enableStun.addEventListener('change', () => this.onStunEnableChange());
        this.elements.stunPreset.addEventListener('change', () => this.onStunPresetChange());
        
        // 监听页面关闭事件
        window.addEventListener('beforeunload', () => {
            this.cleanup();
        });
        
        // 初始化STUN配置UI
        this.onStunEnableChange();
    }
    
    checkBrowserSupport() {
        this.log('浏览器检查', '开始检查浏览器WebRTC支持', 'info');
        
        const checks = {
            'WebRTC支持': !!window.RTCPeerConnection,
            'getUserMedia支持': !!(navigator.mediaDevices && navigator.mediaDevices.getUserMedia),
            'WebSocket支持': !!window.WebSocket,
            'Promise支持': !!window.Promise
        };
        
        let allSupported = true;
        for (const [feature, supported] of Object.entries(checks)) {
            if (supported) {
                this.log('浏览器检查', `✅ ${feature}`, 'success');
            } else {
                this.log('浏览器检查', `❌ ${feature}`, 'error');
                allSupported = false;
            }
        }
        
        if (allSupported) {
            this.log('浏览器检查', '✅ 浏览器完全支持WebRTC', 'success');
        } else {
            this.log('浏览器检查', '❌ 浏览器不完全支持WebRTC，可能影响测试', 'error');
        }
        
        // 显示浏览器信息
        this.log('浏览器信息', `User Agent: ${navigator.userAgent}`, 'debug');
        this.log('浏览器信息', `Platform: ${navigator.platform}`, 'debug');
    }
    
    onStunEnableChange() {
        const enabled = this.elements.enableStun.checked;
        this.elements.stunServerGroup.style.display = enabled ? 'flex' : 'none';
        this.elements.stunPreset.parentElement.style.display = enabled ? 'flex' : 'none';
        
        if (enabled) {
            this.log('STUN配置', '✅ STUN服务器已启用', 'info');
        } else {
            this.log('STUN配置', '❌ STUN服务器已禁用（仅使用host候选）', 'warn');
        }
    }
    
    onStunPresetChange() {
        const preset = this.elements.stunPreset.value;
        if (preset !== 'custom') {
            this.elements.stunServer.value = this.stunPresets[preset];
            this.log('STUN配置', `应用预设配置: ${preset}`, 'info');
        } else {
            this.log('STUN配置', '切换到自定义配置模式', 'info');
        }
    }
    
    getICEConfiguration() {
        const configuration = { iceServers: [] };
        
        if (this.elements.enableStun.checked) {
            const stunServers = this.elements.stunServer.value.trim();
            if (stunServers) {
                // 支持多个STUN服务器，用逗号分隔
                const servers = stunServers.split(',').map(server => server.trim()).filter(server => server);
                configuration.iceServers = servers.map(server => ({ urls: server }));
                this.log('STUN配置', `使用STUN服务器: ${servers.join(', ')}`, 'info');
            } else {
                this.log('STUN配置', '⚠️ STUN已启用但未配置服务器地址', 'warn');
            }
        } else {
            this.log('STUN配置', '仅使用host候选（无STUN服务器）', 'info');
        }
        
        return configuration;
    }
    
    async connect() {
        try {
            const serverUrl = this.elements.serverUrl.value.trim();
            if (!serverUrl) {
                throw new Error('请输入服务器地址');
            }
            
            this.log('连接', `正在连接到服务器: ${serverUrl}`, 'info');
            this.updateConnectionStatus('connecting', '🔄 正在连接...');
            this.updateProgress(10);
            
            // 创建WebSocket连接
            this.ws = new WebSocket(serverUrl);
            
            // 设置连接超时
            const connectTimeout = setTimeout(() => {
                if (this.ws.readyState !== WebSocket.OPEN) {
                    this.ws.close();
                    this.log('连接', '❌ 连接超时 (10秒)', 'error');
                    this.updateConnectionStatus('disconnected', '❌ 连接超时');
                }
            }, 10000);
            
            this.ws.onopen = () => {
                clearTimeout(connectTimeout);
                this.log('连接', '✅ WebSocket连接成功', 'success');
                this.updateConnectionStatus('connected', '✅ 已连接');
                this.updateProgress(30);
                this.updateWSStatus('✅');
                
                this.elements.connectBtn.disabled = true;
                this.elements.disconnectBtn.disabled = false;
                this.elements.startTestBtn.disabled = false;
                
                // 发送ping测试延迟
                this.sendPing();
            };
            
            this.ws.onmessage = (event) => {
                this.handleWebSocketMessage(event);
            };
            
            this.ws.onerror = (error) => {
                clearTimeout(connectTimeout);
                this.log('连接', `❌ WebSocket错误: ${error}`, 'error');
                this.updateConnectionStatus('disconnected', '❌ 连接错误');
                this.updateWSStatus('❌');
            };
            
            this.ws.onclose = (event) => {
                clearTimeout(connectTimeout);
                this.log('连接', `WebSocket连接关闭 - Code: ${event.code}, Reason: ${event.reason}`, 'warn');
                this.updateConnectionStatus('disconnected', '❌ 连接已断开');
                this.updateWSStatus('❌');
                
                this.elements.connectBtn.disabled = false;
                this.elements.disconnectBtn.disabled = true;
                this.elements.startTestBtn.disabled = true;
                this.elements.stopTestBtn.disabled = true;
            };
            
        } catch (error) {
            this.log('连接', `❌ 连接失败: ${error.message}`, 'error');
            this.updateConnectionStatus('disconnected', '❌ 连接失败');
        }
    }
    
    disconnect() {
        this.log('连接', '正在断开连接...', 'info');
        this.cleanup();
    }
    
    cleanup() {
        if (this.statsInterval) {
            clearInterval(this.statsInterval);
            this.statsInterval = null;
        }
        
        if (this.pc) {
            this.pc.close();
            this.pc = null;
            this.log('WebRTC', 'PeerConnection已关闭', 'info');
        }
        
        if (this.localStream) {
            this.localStream.getTracks().forEach(track => track.stop());
            this.localStream = null;
            this.log('媒体', '本地媒体流已停止', 'info');
        }
        
        if (this.ws) {
            this.ws.close();
            this.ws = null;
        }
        
        this.updateConnectionStatus('disconnected', '❌ 未连接');
        this.updateProgress(0);
        this.updateAllStatus('❌');
        
        this.elements.connectBtn.disabled = false;
        this.elements.disconnectBtn.disabled = true;
        this.elements.startTestBtn.disabled = true;
        this.elements.stopTestBtn.disabled = true;
    }
    
    async startWebRTCTest() {
        try {
            this.log('WebRTC测试', '🚀 开始WebRTC连接测试', 'info');
            this.testStartTime = Date.now();
            this.updateProgress(40);
            
            this.elements.startTestBtn.disabled = true;
            this.elements.stopTestBtn.disabled = false;
            
            // 步骤1: 获取本地媒体流（可选）
            await this.setupLocalMedia();
            this.updateProgress(50);
            
            // 步骤2: 创建PeerConnection
            await this.createPeerConnection();
            this.updateProgress(60);
            
            // 步骤3: 创建并发送offer
            await this.createAndSendOffer();
            this.updateProgress(70);
            
            // 开始统计信息收集
            this.startStatsCollection();
            
        } catch (error) {
            this.log('WebRTC测试', `❌ 测试失败: ${error.message}`, 'error');
            this.elements.startTestBtn.disabled = false;
            this.elements.stopTestBtn.disabled = true;
        }
    }
    
    stopWebRTCTest() {
        this.log('WebRTC测试', '⏹️ 停止WebRTC测试', 'info');
        
        if (this.statsInterval) {
            clearInterval(this.statsInterval);
            this.statsInterval = null;
        }
        
        if (this.pc) {
            this.pc.close();
            this.pc = null;
            this.updatePCStatus('❌');
            this.updateICEStatus('❌');
        }
        
        if (this.localStream) {
            this.localStream.getTracks().forEach(track => track.stop());
            this.localStream = null;
        }
        
        this.elements.localVideo.srcObject = null;
        this.elements.remoteVideo.srcObject = null;
        
        this.updateMediaStatus('❌');
        this.updateProgress(30);
        
        this.elements.startTestBtn.disabled = false;
        this.elements.stopTestBtn.disabled = true;
    }
    
    async setupLocalMedia() {
        try {
            this.log('媒体', '正在获取本地媒体流...', 'info');
            
            // 尝试获取摄像头和麦克风
            const constraints = {
                video: { width: 640, height: 480 },
                audio: true
            };
            
            this.localStream = await navigator.mediaDevices.getUserMedia(constraints);
            this.elements.localVideo.srcObject = this.localStream;
            
            this.log('媒体', `✅ 获取本地媒体流成功 - 视频轨道: ${this.localStream.getVideoTracks().length}, 音频轨道: ${this.localStream.getAudioTracks().length}`, 'success');
            
        } catch (error) {
            this.log('媒体', `⚠️ 无法获取本地媒体流: ${error.message} (这不会影响接收测试)`, 'warn');
            this.localStream = null;
        }
    }
    
    async createPeerConnection() {
        try {
            this.log('WebRTC', '正在创建PeerConnection...', 'info');
            
            const configuration = this.getICEConfiguration();
            
            this.log('WebRTC', `ICE服务器配置: ${JSON.stringify(configuration)}`, 'debug');
            
            this.pc = new RTCPeerConnection(configuration);
            
            // 设置事件监听器
            this.pc.onconnectionstatechange = () => {
                const state = this.pc.connectionState;
                this.log('WebRTC', `连接状态变化: ${state}`, 'info');
                this.updatePCStatus(this.getStatusIcon(state));
                
                if (state === 'connected') {
                    this.log('WebRTC', '✅ WebRTC连接建立成功!', 'success');
                    this.updateProgress(90);
                } else if (state === 'failed') {
                    this.log('WebRTC', '❌ WebRTC连接失败', 'error');
                } else if (state === 'disconnected') {
                    this.log('WebRTC', '⚠️ WebRTC连接断开', 'warn');
                }
            };
            
            this.pc.oniceconnectionstatechange = () => {
                const state = this.pc.iceConnectionState;
                this.log('ICE', `ICE连接状态: ${state}`, 'info');
                this.updateICEStatus(this.getStatusIcon(state));
                
                if (state === 'connected' || state === 'completed') {
                    this.log('ICE', '✅ ICE连接建立成功!', 'success');
                } else if (state === 'failed') {
                    this.log('ICE', '❌ ICE连接失败 - 可能是防火墙或NAT问题', 'error');
                } else if (state === 'disconnected') {
                    this.log('ICE', '⚠️ ICE连接断开', 'warn');
                }
            };
            
            this.pc.onicegatheringstatechange = () => {
                this.log('ICE', `ICE收集状态: ${this.pc.iceGatheringState}`, 'debug');
            };
            
            this.pc.onicecandidate = (event) => {
                if (event.candidate) {
                    this.log('ICE', `发现ICE候选: ${event.candidate.candidate}`, 'debug');
                    this.sendMessage({
                        type: 'ice-candidate',
                        candidate: event.candidate
                    });
                } else {
                    this.log('ICE', 'ICE候选收集完成', 'info');
                }
            };
            
            this.pc.ontrack = (event) => {
                this.log('媒体', `接收到远程轨道: ${event.track.kind}`, 'success');
                
                if (!this.remoteStream) {
                    this.remoteStream = new MediaStream();
                    this.elements.remoteVideo.srcObject = this.remoteStream;
                }
                
                this.remoteStream.addTrack(event.track);
                this.updateMediaStatus('✅');
                this.updateProgress(100);
                
                // 监听轨道状态
                event.track.onended = () => {
                    this.log('媒体', `远程轨道结束: ${event.track.kind}`, 'warn');
                };
            };
            
            // 如果有本地流，添加到PeerConnection
            if (this.localStream) {
                this.localStream.getTracks().forEach(track => {
                    this.pc.addTrack(track, this.localStream);
                    this.log('媒体', `添加本地轨道: ${track.kind}`, 'info');
                });
            }
            
            this.log('WebRTC', '✅ PeerConnection创建成功', 'success');
            
        } catch (error) {
            this.log('WebRTC', `❌ 创建PeerConnection失败: ${error.message}`, 'error');
            throw error;
        }
    }
    
    async createAndSendOffer() {
        try {
            this.log('WebRTC', '正在创建Offer...', 'info');
            
            const offer = await this.pc.createOffer({
                offerToReceiveAudio: true,
                offerToReceiveVideo: true
            });
            
            this.log('WebRTC', 'Offer创建成功，设置本地描述...', 'info');
            this.log('SDP', `本地Offer SDP:\n${offer.sdp}`, 'debug');
            
            await this.pc.setLocalDescription(offer);
            this.log('WebRTC', '✅ 本地描述设置成功', 'success');
            
            // 发送offer到服务器
            this.sendMessage({
                type: 'offer',
                sdp: offer.sdp
            });
            
            this.log('WebRTC', '📤 Offer已发送到服务器', 'info');
            
        } catch (error) {
            this.log('WebRTC', `❌ 创建或发送Offer失败: ${error.message}`, 'error');
            throw error;
        }
    }
    
    async handleWebSocketMessage(event) {
        try {
            const message = JSON.parse(event.data);
            this.log('消息', `收到服务器消息: ${message.type}`, 'info');
            
            switch (message.type) {
                case 'answer':
                    await this.handleAnswer(message);
                    break;
                case 'ice-candidate':
                    await this.handleIceCandidate(message);
                    break;
                case 'pong':
                    this.handlePong(message);
                    break;
                case 'error':
                    this.log('服务器错误', message.message, 'error');
                    break;
                default:
                    this.log('消息', `未知消息类型: ${message.type}`, 'warn');
            }
        } catch (error) {
            this.log('消息', `❌ 处理消息失败: ${error.message}`, 'error');
        }
    }
    
    async handleAnswer(message) {
        try {
            this.log('WebRTC', '收到服务器Answer，设置远程描述...', 'info');
            this.log('SDP', `远程Answer SDP:\n${message.sdp}`, 'debug');
            
            const answer = new RTCSessionDescription({
                type: 'answer',
                sdp: message.sdp
            });
            
            await this.pc.setRemoteDescription(answer);
            this.log('WebRTC', '✅ 远程描述设置成功', 'success');
            
        } catch (error) {
            this.log('WebRTC', `❌ 处理Answer失败: ${error.message}`, 'error');
        }
    }
    
    async handleIceCandidate(message) {
        try {
            this.log('ICE', '收到服务器ICE候选', 'debug');
            
            if (message.candidate) {
                await this.pc.addIceCandidate(new RTCIceCandidate(message.candidate));
                this.log('ICE', '✅ ICE候选添加成功', 'debug');
            }
        } catch (error) {
            this.log('ICE', `❌ 添加ICE候选失败: ${error.message}`, 'error');
        }
    }
    
    sendPing() {
        const pingTime = Date.now();
        this.sendMessage({
            type: 'ping',
            timestamp: pingTime
        });
        this.log('网络', '📡 发送Ping测试', 'debug');
    }
    
    handlePong(message) {
        const now = Date.now();
        const latency = now - message.timestamp;
        this.log('网络', `🏓 Pong收到，延迟: ${latency}ms`, 'info');
    }
    
    sendMessage(message) {
        if (this.ws && this.ws.readyState === WebSocket.OPEN) {
            this.ws.send(JSON.stringify(message));
            this.log('消息', `📤 发送: ${message.type}`, 'debug');
        } else {
            this.log('消息', '❌ WebSocket未连接，无法发送消息', 'error');
        }
    }
    
    startStatsCollection() {
        this.log('统计', '开始收集WebRTC统计信息...', 'info');
        
        this.statsInterval = setInterval(async () => {
            if (this.pc) {
                try {
                    const stats = await this.pc.getStats();
                    this.processStats(stats);
                } catch (error) {
                    this.log('统计', `获取统计信息失败: ${error.message}`, 'error');
                }
            }
        }, 5000); // 每5秒收集一次
    }
    
    processStats(stats) {
        let inboundVideo = null;
        let inboundAudio = null;
        let outboundVideo = null;
        let outboundAudio = null;
        let candidatePairs = [];
        
        stats.forEach(report => {
            if (report.type === 'inbound-rtp' && report.kind === 'video') {
                inboundVideo = report;
            } else if (report.type === 'inbound-rtp' && report.kind === 'audio') {
                inboundAudio = report;
            } else if (report.type === 'outbound-rtp' && report.kind === 'video') {
                outboundVideo = report;
            } else if (report.type === 'outbound-rtp' && report.kind === 'audio') {
                outboundAudio = report;
            } else if (report.type === 'candidate-pair' && report.state === 'succeeded') {
                candidatePairs.push(report);
            }
        });
        
        // 记录接收统计
        if (inboundVideo) {
            this.log('统计', `📹 视频接收 - 包数: ${inboundVideo.packetsReceived}, 字节: ${inboundVideo.bytesReceived}, 丢包: ${inboundVideo.packetsLost || 0}`, 'info');
        }
        
        if (inboundAudio) {
            this.log('统计', `🔊 音频接收 - 包数: ${inboundAudio.packetsReceived}, 字节: ${inboundAudio.bytesReceived}, 丢包: ${inboundAudio.packetsLost || 0}`, 'info');
        }
        
        // 记录发送统计
        if (outboundVideo) {
            this.log('统计', `📹 视频发送 - 包数: ${outboundVideo.packetsSent}, 字节: ${outboundVideo.bytesSent}`, 'debug');
        }
        
        if (outboundAudio) {
            this.log('统计', `🔊 音频发送 - 包数: ${outboundAudio.packetsSent}, 字节: ${outboundAudio.bytesSent}`, 'debug');
        }
        
        // 记录连接统计
        candidatePairs.forEach(pair => {
            if (pair.currentRoundTripTime) {
                this.log('统计', `🌐 RTT: ${(pair.currentRoundTripTime * 1000).toFixed(2)}ms`, 'info');
            }
        });
    }
    
    getStatusIcon(state) {
        const stateMap = {
            'new': '🔄',
            'connecting': '🔄',
            'connected': '✅',
            'completed': '✅',
            'disconnected': '⚠️',
            'failed': '❌',
            'closed': '❌'
        };
        return stateMap[state] || '❓';
    }
    
    updateConnectionStatus(state, text) {
        this.connectionState = state;
        this.elements.connectionStatus.textContent = text;
        this.elements.connectionStatus.className = `status ${state}`;
    }
    
    updateProgress(percentage) {
        this.elements.progressFill.style.width = `${percentage}%`;
    }
    
    updateWSStatus(status) {
        this.elements.wsStatus.textContent = status;
    }
    
    updatePCStatus(status) {
        this.elements.pcStatus.textContent = status;
    }
    
    updateICEStatus(status) {
        this.elements.iceStatus.textContent = status;
    }
    
    updateMediaStatus(status) {
        this.elements.mediaStatus.textContent = status;
    }
    
    updateAllStatus(status) {
        this.updateWSStatus(status);
        this.updatePCStatus(status);
        this.updateICEStatus(status);
        this.updateMediaStatus(status);
    }
    
    log(category, message, level = 'info') {
        const timestamp = new Date().toLocaleTimeString();
        const logEntry = document.createElement('div');
        logEntry.className = `log-entry ${level}`;
        logEntry.textContent = `[${timestamp}] [${category}] ${message}`;
        
        this.elements.logContainer.appendChild(logEntry);
        this.elements.logContainer.scrollTop = this.elements.logContainer.scrollHeight;
        
        // 同时输出到控制台
        const consoleMethod = level === 'error' ? 'error' : level === 'warn' ? 'warn' : 'log';
        console[consoleMethod](`[${category}] ${message}`);
    }
    
    clearLog() {
        this.elements.logContainer.innerHTML = '<div class="log-entry info">[系统] 日志已清空</div>';
    }
}

// 初始化客户端
const client = new WebRTCTestClient();

// 导出到全局作用域以便调试
window.webrtcClient = client;